﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Uniforax.Core.Common;
using Uniforax.Core.WorldFramework;

namespace Uniforax.Core.GameActions
{
    /*
     * 比如创建了一个单位，然后单位落地会造成震荡，地面会塌陷，资源格资源会受到影响。
     * 动作记录：创建单位（会描述指定位置，记录创建完的对象的id，然后执行单位内部的事件）
     * 动作记录2：执行单位内部的事件，追加地面范围伤害（伤害信息），追加资源格影响
     * 动作记录3：执行并记录伤害回调，对谁造成了伤害，进入伤害计算流程。
     * 资源影响->地面塌陷复原->单位销毁（反向过程）
     * 入口：单位创建（单位内部可能定义了影响）
     * On事件：只能执行Action
     * Action：执行具体内容，但是不能创建和执行Action，但是可以执行对应的On事件。
     * 只有事件才能在上下文中添加记录。
     */

    ///<summary></summary>
    public class CreateGameObjectAction : BaseGameAction
    {
        #region props

        public BaseBluePrint BluePrint { get; set; }
        public PosId PosId { get; set; }

        #endregion

        #region for undo

        public string NewId { get; set; }

        #endregion

        #region ctors

        public CreateGameObjectAction(BaseBluePrint bluePrint, PosId posId)
        {
            PosId = posId;
        }

        #endregion

        #region methods

        public override void Execute(ActionContext context)
        {
            var world = context.GameWorld;
            GameObjects.BaseGameObject gameObject = CreateGameObject();

            gameObject.CreateStatus = CreateStatus.BeforeCreate;

            gameObject.OnCreate(context);

            var grid = world.GetGrid(PosId);

            ObjectEnterToGrid(context, gameObject, grid);

            gameObject.CreateStatus = CreateStatus.BeforePlace;

            ObjectPlacedInGrid(context, gameObject, grid);

            gameObject.CreateStatus = CreateStatus.Completed;
        }

        private static void ObjectPlacedInGrid(ActionContext context, GameObjects.BaseGameObject gameObject, Grid grid)
        {
            var placeContext = new GameObjectPlaceGridMovementContext()
            {
                GameObject = gameObject,
                CurrentGrid = grid
            };

            grid.PlaceObject(gameObject);
            grid.OnGameObjectPlaced(context, placeContext);
            gameObject.OnPlacedGrid(context, placeContext);
        }

        private static void ObjectEnterToGrid(ActionContext context, GameObjects.BaseGameObject gameObject, Grid grid)
        {
            var enterContext = new GameObjectEnterGridMovementContext()
            {
                GameObject = gameObject,
                NewGrid = grid
            };
            grid.OnGameObjectEnter(context, enterContext);
            gameObject.OnEnterGrid(context, enterContext);
        }

        // 从蓝图创建某个对象。
        private GameObjects.BaseGameObject CreateGameObject()
        {
            var gameObject = BluePrint.CreateGameObject();

            NewId = Guid.NewGuid().ToString();
            gameObject.ObjectId = NewId;
            return gameObject;
        }

        public override void Undo(ActionContext context)
        {
            var world = context.GameWorld;
            var posId = PosId;
            var grid = world.GetGrid(posId);

            var objectId = NewId;
            var gameObject = grid.GetPlacedObject(objectId);
            gameObject.CreateStatus =  CreateStatus.BeforeCreate;
            grid.RemovePlacedObject(gameObject);
        }

        #endregion

    }
}
